<?php

namespace Params;

/**
 * Class Params
 *
 * @package Params
 * @author  Jon
 * @link    https://gitee.com/joncc/params
 */
class Params
{
    private static $is_request = false;
    private static $is_get = false;
    private static $is_post = false;
    private static $is_file = false;
    private static $is_cookie = false;
    private static $is_session = false;
    private static $is_server = false;
    private static $is_env = false;
    private static $is_input = false;
    private static $is_argv = false;

    private $data = [];

    /**
     * Params constructor.
     */
    private function __construct()
    {
    }

    /**
     * @return Params
     */
    public static function requestBuilder()
    {
        self::$is_request = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function getBuilder()
    {
        self::$is_get = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function postBuilder()
    {
        self::$is_post = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function fileBuilder()
    {
        self::$is_file = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function cookieBuilder()
    {
        self::$is_cookie = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function sessionBuilder()
    {
        self::$is_session = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function serverBuilder()
    {
        self::$is_server = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function envBuilder()
    {
        self::$is_env = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function inputBuilder()
    {
        self::$is_input = true;
        return new static();
    }

    /**
     * @return Params
     */
    public static function argvBuilder()
    {
        self::$is_argv = true;
        return new static();
    }

    /**
     * @return $this
     */
    public function build()
    {
        $params = [];
        if (self::$is_request) {
            $params = $_REQUEST;
        } elseif (self::$is_get) {
            $params = $_GET;
        } elseif (self::$is_post) {
            $params = $_POST;
        } elseif (self::$is_argv) {
            global $argv;
            $params = $argv;
        } elseif (self::$is_input) {
            $params = file_get_contents('php://input');
        } elseif (self::$is_file) {
            $params = $_FILES;
        } elseif (self::$is_cookie) {
            $params = $_COOKIE;
        } elseif (self::$is_session) {
            $params = $_SESSION;
        } elseif (self::$is_server) {
            $params = $_SERVER;
        } elseif (self::$is_env) {
            $params = $_ENV;
        }

        if (!is_array($params) || empty($params)) {
            $this->data = $params;
            return $this;
        }

        foreach ($params as $name => $value) {
            $set_method1 = 'set' . ucwords($name);
            $set_method2 = 'set_' . $name;
            $set_method3 = $name;

            if (method_exists($this, $set_method1)) {
                $this->data[$name] = $this->$set_method1($value);
            } elseif (method_exists($this, $set_method2)) {
                $this->data[$name] = $this->$set_method2($value);
            } elseif (method_exists($this, $set_method3)) {
                $this->data[$name] = $this->$set_method3($value);
            } else {
                $this->data[$name] = $value;
            }
        }

        return $this;
    }

    /**
     * @param $name
     * @param null $default
     * @return mixed|null
     */
    public function get($name, $default = null)
    {
        if (isset($this->data[$name])) {
            return $this->data[$name];
        } elseif (!isset($this->data[$name]) && !is_null($default)) {
            return $default;
        } else {
            return null;
        }
    }

    /**
     * @return array
     */
    public function getAll()
    {
        return $this->data;
    }
}